package com.zbkj.crmeb.handler.orderproduct;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.crmeb.core.config.MybatisPlusConfig;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.TableNameUtil;
import com.factory.PushWarehouseFactory;
import com.utils.monitor.DingMsgEnum;
import com.utils.monitor.DingTalkMsgUtil;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import com.zbkj.crmeb.enums.BusinessTypeEnums;
import com.zbkj.crmeb.enums.plat.PlatPushStatusEnums;
import com.zbkj.crmeb.front.response.ProductDetailResponse;
import com.zbkj.crmeb.merchant.api.service.MerProductService;
import com.zbkj.crmeb.plat.by.dto.attributes.SaleAttribute;
import com.zbkj.crmeb.plat.by.dto.*;
import com.zbkj.crmeb.plat.by.enums.ByCustomsCode;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.response.StoreProductAttrValueResponse;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.tools.model.MoneyExchange;
import com.zbkj.crmeb.tools.service.MoneyExchangeService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.weaver.ast.Var;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author: wsl
 * @date: 2024/2/22 0022 22:28
 * @ClassName: ByOrderConfirmHandler
 */
@Component("byOrderProductHandler")
public class ByOrderProductHandler extends AbstractOrderProductHandler {
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private StoreProductAttrService storeProductAttrService;
    @Autowired
    private StoreProductDescriptionService storeProductDescriptionService;
    @Autowired
    private MerProductService productService;
    @Autowired
    private MoneyExchangeService moneyExchangeService;
    @Autowired
    private StoreProductLogService storeProductLogService;
    @Autowired
    private ICategoryMatchService categoryMatchService;
    @Autowired
    private StoreBrandService storeBrandService;
    @Autowired
    private PushWarehouseFactory pushWarehouseFactory;
    @Autowired
    private RelationService relationService;

    @Value("${by.plat.url}")
    private String url;

    @Value("${by.plat.key}")
    private String key;


    private static final Logger logger = LoggerFactory.getLogger(ByOrderProductHandler.class);

    @Override
    public boolean doPreCheck(OrderProductContext context) {
        return true;
    }

    @Override
    public Result doHandler(OrderProductContext context) {
        Result result = new Result();
        String productId = context.getProductId();
        // 查询商品信息
        StoreProduct storeProduct = context.getStoreProduct();
        if (null == storeProduct){
            storeProduct = storeProductService.getById(productId);
            context.setStoreProduct(storeProduct);
        }
        // 查询sku信息
        List<StoreProductAttrValue> storeProductAttrValues = context.getStoreProductAttrValues();
        if (CollectionUtils.isEmpty(storeProductAttrValues)){
            storeProductAttrValues = storeProductAttrValueService.getListByProductId(Integer.valueOf(productId));
            context.setStoreProductAttrValues(storeProductAttrValues);
        }
        List<String> validateList = new ArrayList<>();
        // 组装别样商品参数
        ApiProduct apiProduct = assembledProduct(context,storeProduct,storeProductAttrValues,validateList);
        context.setValidateList(validateList);
        if (null == apiProduct){
            result.setData(validateList);
            result.setSuccess(false);
            return result;
        }
        // 推送别样平台
        MultiValueMap<String,String> header = new LinkedMultiValueMap<>();
        header.put("Authorization",Collections.singletonList(key));
        String response = post(url+"/inventory/api/v1/products", JSON.toJSONString(apiProduct), header);
//        DingTalkMsgUtil.sendMsg(DingMsgEnum.PLAT,"推送商品记录："+response);
        logger.error("推送商品记录:{}",response);
        JSONObject jsonObject = JSON.parseObject(response);
        // 失败
        if (null != jsonObject.get("error")){
            ByResult byResult = JSON.parseObject(response, ByResult.class);
            validateList.add(byResult.getError().getMessage());
            result.setData(validateList);
            result.setMessage(byResult.getError().getMessage());
            result.setSuccess(false);
            context.setValidateList(validateList);
            return result;
        }
        // 解析返回数据
        apiProduct = JSON.parseObject(response,ApiProduct.class);
        if (CollectionUtils.isNotEmpty(validateList)){
            result.setData(validateList);
        }
        context.setApiProduct(apiProduct);
        result.setSuccess(true);
        context.setValidateList(validateList);
        return result;
    }

    private void matchCategoryAndBrand(OrderProductContext context, StoreProduct storeProduct) {
        Integer cateId = storeProduct.getCateId();
        Integer brandId = storeProduct.getBrandId();
        if (null == cateId || null == brandId){
            throw new CrmebException("商品分类或者品牌缺失");
        }
        CategoryMatch categoryMatch = categoryMatchService.getById(cateId);
        if (null != categoryMatch){
            context.setCategoryId(categoryMatch.getByCategoryId());
        }
        StoreBrand storeBrand = storeBrandService.getById(brandId);
        if (null != storeBrand){
            context.setBrandId(storeBrand.getByBrandId());
        }

    }

    @Override
    public void doAfter(OrderProductContext context,Result result) {
        ApiProduct apiProduct = context.getApiProduct();
        // 处理商品数据
        handleProductAfter(apiProduct,context,result);
        // 处理SKU数据
        handleSkuAfter(apiProduct,context,result);
    }

    private void handleProductAfter(ApiProduct apiProduct, OrderProductContext context, Result result) {
        StoreProduct storeProduct = context.getStoreProduct();
        // 更新推送标记
        String pushPlat = result.isSuccess()?ByCommonConstant.BY_UP: PlatPushStatusEnums.PUSH_FAIL.getCode();
        Relation productRelation = relationService.getOne(Wrappers.<Relation>lambdaQuery().eq(Relation::getBusinessCode,storeProduct.getId()).eq(Relation::getBusinessType,BusinessTypeEnums.PUSH_PRODUCT_PLAT_OF_BY.getCode()));
        if (null == productRelation){
            productRelation = Relation.buildRelation(String.valueOf(storeProduct.getId()),BusinessTypeEnums.PUSH_PRODUCT_PLAT_OF_BY,pushPlat);
        }
        productRelation.setSubCode(pushPlat);
        String msg = result.isSuccess()?"商品推送别样平台成功":"推送失败:"+result.getMessage();
        if (null != apiProduct){
            productRelation.addFeature(ByCommonConstant.PLAT_PRODUCT_ID,apiProduct.getId());
            productRelation.addFeature(ByCommonConstant.MERCHANT_PRODUCT_ID,apiProduct.getMerchantProductId());
        }
        if (null == productRelation.getId()){
            relationService.save(productRelation);
        }else {
            relationService.updateById(productRelation);
        }
        List<String> validateList = context.getValidateList();
        // 保存日志
        List<StoreProductLog> storeProductLogs = new ArrayList<>();
        storeProductLogs.add(StoreProductLog.assembledLog(String.valueOf(storeProduct.getId()),msg));
        validateList.forEach(item->storeProductLogs.add(StoreProductLog.assembledLog(String.valueOf(storeProduct.getId()),item)));
        storeProductLogService.saveOrUpdateBatch(storeProductLogs);
    }

    private void handleSkuAfter(ApiProduct apiProduct, OrderProductContext context, Result result) {
        if (null == apiProduct){
            return;
        }
        List<StoreProductAttrValue> storeProductAttrValues = context.getStoreProductAttrValues();
        if (CollectionUtils.isEmpty(storeProductAttrValues)){
            return;
        }
        Map<Integer, StoreProductAttrValue> map = new HashMap<>();
        List<String> attrValueIds = new ArrayList<>();
        for (StoreProductAttrValue storeProductAttrValue : storeProductAttrValues) {
            map.put(storeProductAttrValue.getId(),storeProductAttrValue);
            attrValueIds.add(String.valueOf(storeProductAttrValue.getId()));
        }
        List<Relation> relations = relationService.list(Wrappers.<Relation>lambdaQuery().in(Relation::getBusinessCode, attrValueIds).eq(Relation::getBusinessType, BusinessTypeEnums.PUSH_SKU_PLAT_OF_BY.getCode()));
        Map<String, Relation> relationMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(relations)){
            relationMap = relations.stream().collect(Collectors.toMap(Relation::getBusinessCode, v->v));
        }
        List<Relation> updateRelations = new ArrayList<>();
        List<Relation> insertRelations = new ArrayList<>();
        for (Sku sku : apiProduct.getSkus()) {
            String[] split = sku.getMerchantSkuId().split("SUYUN");
            if (split.length < 2 || !map.containsKey(Integer.valueOf(split[1]))){
                continue;
            }
            StoreProductAttrValue storeProductAttrValue = map.get(Integer.valueOf(split[1]));
            Relation skuRelation = relationMap.get(split[1]);
            if (null == skuRelation){
                skuRelation = Relation.buildRelation(split[1],BusinessTypeEnums.PUSH_SKU_PLAT_OF_BY,ByCommonConstant.BY_UP);
                insertRelations.add(skuRelation);
            }else {
                updateRelations.add(skuRelation);
            }
            skuRelation.addFeature(ByCommonConstant.PUSH_PLAT,"Y");
            skuRelation.addFeature(ByCommonConstant.ORIGIN_STOCK,String.valueOf(storeProductAttrValue.getStock()));
            skuRelation.addFeature(ByCommonConstant.PUSH_PRICE,String.valueOf(storeProductAttrValue.getPrice()));
            skuRelation.addFeature(ByCommonConstant.PLAT_SKU_ID,sku.getId());
            skuRelation.addFeature(ByCommonConstant.MERCHANT_SKU_ID,sku.getMerchantSkuId());
            if (null != sku.getSalePrice()){
                skuRelation.addFeature(ByCommonConstant.PLAT_SALE_PRICE,String.valueOf(sku.getSalePrice().getValue()));
            }
            if (null != sku.getOriginalPrice()){
                skuRelation.addFeature(ByCommonConstant.PLAT_ORIGINAL_PRICE,String.valueOf(sku.getOriginalPrice().getValue()));
            }
        }
        if (CollectionUtils.isNotEmpty(updateRelations)){
            for (Relation updateRelation : updateRelations) {
                relationService.updateById(updateRelation);
            }
        }
        if (CollectionUtils.isNotEmpty(insertRelations)){
            relationService.saveBatch(insertRelations);
        }
    }


    private ApiProduct assembledProduct(OrderProductContext context,StoreProduct storeProduct, List<StoreProductAttrValue> storeProductAttrValues, List<String> validateList) {
        ApiProduct apiProduct = new ApiProduct();
        apiProduct.setMerchantProductId(storeProduct.getBarCode().replace(" ",""));
//        apiProduct.setId("avitahk_"+storeProduct.getKeyword());
        // todo
        apiProduct.setBrandId(context.getBrandId());
        apiProduct.setCategoryId(context.getCategoryId());
        apiProduct.setName(storeProduct.getStoreName()+" "+storeProduct.getKeyword());
        apiProduct.setStatus(ByCommonConstant.PLAT_AVAILABLE);
        String productErrorKey = String.format("商品名:%s--->商品id:%s--->异常信息: ",storeProduct.getStoreName(),storeProduct.getId());
        StoreProductDescription storeProductDescription = storeProductDescriptionService.getOne(Wrappers.<StoreProductDescription>lambdaQuery().eq(StoreProductDescription::getProductId, storeProduct.getId()));
        if (StringUtils.isBlank(storeProductDescription.getSliderImage())){
            validateList.add(productErrorKey+"商品缺失主图或轮播图");
            return null;
        }
        // 获取商品属性信息
        List<StoreProductAttr> storeProductAttrs = storeProductAttrService.getByProductId(storeProduct.getId());
        if (CollectionUtils.isEmpty(storeProductAttrs)){
            validateList.add(productErrorKey+"商品缺失属性规格");
            return null;
        }
//        List<String> attrNames = storeProductAttrs.stream().map(StoreProductAttr::getAttrName).collect(Collectors.toList());
        Map<String, StoreProductAttr> attrMap = storeProductAttrs.stream().collect(Collectors.toMap(StoreProductAttr::getAttrName, Function.identity(), (s1, s2) -> s1));
        // todo 主图
//        String mainImageUrl = storeProductDescription.getImage();
        List<ProductImageDTO> mainProductImageDTOS = new ArrayList<>();
        String sliderImage = storeProductDescription.getSliderImage();
        List<String> split = JSON.parseArray(sliderImage, String.class);
        Map<String, ImageUploadResponse> mainImageMap = uploadImages(split);
        if (MapUtils.isEmpty(mainImageMap)){
            validateList.add(productErrorKey+"主图上传失败");
            return null;
        }
        int mainImageIndex = 0;
        for (String imageUrl : split) {
            if (mainImageIndex>4){
                break;
            }
            if (!mainImageMap.containsKey(imageUrl)){
                continue;
            }
            ImageUploadResponse imageUploadResponse = mainImageMap.get(imageUrl);
            if (null == imageUploadResponse){
                continue;
            }
            ProductImageDTO mainImage = new ProductImageDTO();
            mainImage.setId(imageUploadResponse.getId());
            mainImage.setIndex(mainImageIndex);
            mainProductImageDTOS.add(mainImage);
            mainImageIndex++;
        }
        apiProduct.setImages(mainProductImageDTOS);

        // 商品详情数据
        ImageTextDTO imageTextDTO = new ImageTextDTO();
        List<LayerDTO> layerDTOS = new ArrayList<>();
        if (StringUtils.isNotBlank(storeProductDescription.getDescription())){
            LayerDTO layerDTO = new LayerDTO();
            TextDTO textDTO = new TextDTO();
            textDTO.setText(storeProductDescription.getDescription());
            layerDTO.setLayerType("TEXT");
            layerDTO.setText(textDTO);
            layerDTOS.add(layerDTO);
        }
        // 添加公告图片
        ImageUploadResponse noticeImage = FileUploadUtils.uploadImageOfBY("https://italytao.oss-cn-shanghai.aliyuncs.com/suyun/%E5%A2%83%E5%A4%96%E4%BA%A7%E5%93%81%E5%85%AC%E5%91%8A.jpg");
        if (null != noticeImage){
            LayerDTO layerDTO = new LayerDTO();
            ImageDTO imageDTO = new ImageDTO();
            imageDTO.setUrl(noticeImage.getUrl());
            imageDTO.setFormat(noticeImage.getFormat());
            imageDTO.setWidth(noticeImage.getWidth());
            imageDTO.setHeight(noticeImage.getHeight());
            layerDTO.setLayerType("IMAGE");
            layerDTO.setImage(imageDTO);
            layerDTOS.add(layerDTO);
        }
        String sp1 = storeProductDescription.getSp1();
        if (StringUtils.isNotBlank(sp1)){
            List<String> iamgesArray = JSON.parseArray(sp1, String.class);
            Map<String, ImageUploadResponse> imageMap = uploadImages(iamgesArray);
            if (MapUtils.isEmpty(imageMap)){
                validateList.add(productErrorKey+"商品详情图片上传失败");
                return null;
            }
            int descIndex = 0;
            for (String image : iamgesArray) {
                LayerDTO layerDTO = new LayerDTO();
                if (!imageMap.containsKey(image)){
                    continue;
                }
                ImageUploadResponse imageUploadResponse = imageMap.get(image);
                if (null == imageUploadResponse){
                    continue;
                }
                ImageDTO imageDTO = new ImageDTO();
                imageDTO.setUrl(imageUploadResponse.getUrl());
                imageDTO.setFormat(imageUploadResponse.getFormat());
                imageDTO.setWidth(imageUploadResponse.getWidth());
                imageDTO.setHeight(imageUploadResponse.getHeight());
                layerDTO.setImage(imageDTO);
                layerDTO.setLayerType("IMAGE");
                layerDTOS.add(layerDTO);
            }
        }
        if (CollectionUtils.isNotEmpty(layerDTOS)){
            imageTextDTO.setLayers(layerDTOS);
            apiProduct.setDescription(imageTextDTO);
        }
        // 计算金额
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("merId",126);
        THREAD_LOCAL.set(jsonObject);
//        MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(126));
//        MybatisPlusConfig.productValueNameMp.set(TableNameUtil.getProductMerName(126));
//        ProductDetailResponse productDetailResponse = productService.getDetail(storeProduct.getId(), 126, null);
//        if (null == productDetailResponse || CollectionUtils.isEmpty(productDetailResponse.getProductValues())){
//            validateList.add(productErrorKey+"商品金额计算异常");
//            return null;
//        }
//        List<StoreProductAttrValueResponse> productValues = productDetailResponse.getProductValues();
//        Map<String, StoreProductAttrValueResponse> skuInfoMap = productValues.stream().collect(Collectors.toMap(StoreProductAttrValueResponse::getSourceSkuId, v -> v));
        MoneyExchange moneyExchange = moneyExchangeService.getById(12);
        BigDecimal baseExchange = new BigDecimal("7.2");
        if (null != moneyExchange && StringUtils.isNotBlank(moneyExchange.getBankConversionPri())){
            baseExchange = new BigDecimal(moneyExchange.getBankConversionPri());
        }
        // sku数据
        List<Sku> skus = new ArrayList<>();
        for (StoreProductAttrValue storeProductAttrValue : storeProductAttrValues) {
            String skuErrorKey = String.format("商品名:%s--->sku信息:%s--->异常信息: ",storeProduct.getStoreName(),storeProductAttrValue.getSuk());
//            if (!skuInfoMap.containsKey(storeProductAttrValue.getSourceSkuId())){
//                validateList.add(skuErrorKey+"金额异常");
//                continue;
//            }
//            StoreProductAttrValueResponse storeProductAttrValueResponse = skuInfoMap.get(storeProductAttrValue.getSourceSkuId());
            // sku
            Sku sku = new Sku();
            sku.setProductId(apiProduct.getId());
//            if (StringUtils.isBlank(storeProductAttrValue.getSelfSourceSkuId())){
//                validateList.add(skuErrorKey+"自定义skuId为空");
//                continue;
//            }
//            sku.setBarCode(storeProductAttrValue.getSelfSourceSkuId());
//            sku.setMerchantSkuId(storeProductAttrValue.getSelfSourceSkuId());
            sku.setBarCode("SUYUN"+storeProductAttrValue.getId());
            sku.setMerchantSkuId("SUYUN"+storeProductAttrValue.getId());
            // todo
            String image = storeProductAttrValue.getImage();
            ImageUploadResponse imageUploadResponse = FileUploadUtils.uploadImageOfBY(image);
            if (null == imageUploadResponse){
                validateList.add(skuErrorKey+"sku图片上传失败");
                continue;
            }
            ProductImageDTO skuImage = new ProductImageDTO();
            skuImage.setId(imageUploadResponse.getId());
            skuImage.setIndex(0);
            sku.setImages(Collections.singletonList(skuImage));
            // {"颜色":"默认","尺寸":"黑色;85;"}
            if (StringUtils.isBlank(storeProductAttrValue.getAttrValue()) && MapUtils.isEmpty(attrMap)){
                validateList.add(skuErrorKey+"sku缺少产品属性");
                continue;
            }
            JSONObject skuAttribute = JSON.parseObject(StringUtils.defaultString(storeProductAttrValue.getAttrValue(),"{}"));
            List<SaleAttribute> saleAttributes = new ArrayList<>();
            for (Map.Entry<String, StoreProductAttr> entry : attrMap.entrySet()) {
                String attrName = entry.getKey();
                StoreProductAttr value = entry.getValue();
                SaleAttribute saleAttribute = new SaleAttribute();
                String key = "SIZE";
                if (Objects.equals(attrName,"颜色")){
                    key = "COLOR";
                    ProductImageDTO colorImage = new ProductImageDTO();
                    colorImage.setId(imageUploadResponse.getId());
                    saleAttribute.setImage(colorImage);
                }
                saleAttribute.setKey(key);
                String name = StringUtils.defaultString(skuAttribute.getString(attrName), value.getAttrValues());
                if (StringUtils.isBlank(name)){
                    validateList.add(skuErrorKey+"sku缺少产品属性");
                    continue;
                }
                saleAttribute.setName(name);
                saleAttributes.add(saleAttribute);
            }
            if (CollectionUtils.isEmpty(saleAttributes)){
                continue;
            }
            sku.setSaleAttributes(saleAttributes);
            Price salePrice = new Price();
            salePrice.setCurrency("USD");
            salePrice.setValue(storeProductAttrValue.getPrice()
                    .divide(baseExchange,2, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100L)).setScale(2, RoundingMode.DOWN).intValue());
            sku.setSupplyPrice(salePrice);
            sku.setStockNum(storeProductAttrValue.getStock());
            sku.setStatus(ByCommonConstant.PLAT_AVAILABLE);
            // 仓库信息
            sku.setShipping(pushWarehouseFactory.getWarehouseInfo(storeProduct.getSuppliersId()));
            // 清关口岸
            sku.setCustomsClearance(ByCustomsCode.HANGZHOU.name());
            skus.add(sku);
        }
        if (CollectionUtils.isEmpty(skus)){
            validateList.add(productErrorKey+"当前商品没有满足上架条件SKU");
            return null;
        }
        apiProduct.setSkus(skus);
        return apiProduct;

    }

    private Map<String,ImageUploadResponse> uploadImages(List<String> images){
        Map<String, ImageUploadResponse> map = new ConcurrentHashMap<>();

        CompletableFuture[] completableFutures = images.stream().map(k->
                CompletableFuture.runAsync(()->{
                    ImageUploadResponse imageUploadResponse = FileUploadUtils.uploadImageOfBY(k);
                    if (null == imageUploadResponse){
                        return;
                    }
                    map.put(k,imageUploadResponse);
                })
        ).toArray(CompletableFuture[]::new);
        try {
            CompletableFuture.allOf(completableFutures).get(5, TimeUnit.MINUTES);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return map;
    }

    public static String post(String url, String params, MultiValueMap<String, String> headers) {
        return request(url, params, headers, HttpMethod.POST, MediaType.APPLICATION_JSON);
    }

    /**
     * http请求
     *
     * @param url
     * @param params    请求参数
     * @param headers   请求头
     * @param method    请求方式
     * @param mediaType 参数类型
     * @return
     */
    public static String request(String url, Object params, MultiValueMap<String, String> headers, HttpMethod method, MediaType mediaType) {
        if (url == null || url.trim().isEmpty()) {
            return null;
        }
        RestTemplate client = new RestTemplate();
        // header
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null) {
            httpHeaders.addAll(headers);
        }
        // 提交方式：表单、json
        httpHeaders.setContentType(mediaType);
        HttpEntity<Object> httpEntity = new HttpEntity(params, httpHeaders);
        ResponseEntity<String> response = client.exchange(url, method, httpEntity, String.class);
        return response.getBody();
    }




}
